package cn.tedu.mall.seckill.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.JsonPage;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.pojo.seckill.vo.SeckillSpuDetailSimpleVO;
import cn.tedu.mall.pojo.seckill.vo.SeckillSpuVO;
import cn.tedu.mall.seckill.service.ISeckillSpuService;
import cn.tedu.mall.seckill.util.RedisBloomUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class SeckillSpuServiceImpl implements ISeckillSpuService {

    @Autowired
    private RedisTemplate redisTemplate;
    public static final String SECKILL_SPUS_KEY="seckill:spus";
    public static final String SECKILL_SPU_PREFIX="seckill:spu:";
    @Autowired
    private RedisBloomUtils redisBloomUtils;
    public static final String SECKILL_BLOOM_SPUS_KEY="seckill:bloom:spus";

    @Override
    public JsonPage<SeckillSpuVO> listSeckillSpus(Integer page, Integer pageSize) {
        List<SeckillSpuVO> spuVOList = (List<SeckillSpuVO>)redisTemplate.opsForValue().get(SECKILL_SPUS_KEY);
        if (spuVOList==null || spuVOList.size()==0){
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"当前缓存没有数据，请检查预热逻辑");
        }
        return JsonPage.defaultPage(spuVOList);
    }

    @Override
    public SeckillSpuVO getSeckillSpu(Long spuId) {
        Boolean bfexists = redisBloomUtils.bfexists(SECKILL_BLOOM_SPUS_KEY, spuId + "");
        if (!bfexists){
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"当前数据中没有spuId:"+spuId);
        }
        SeckillSpuVO seckillSpuVO = (SeckillSpuVO) redisTemplate.opsForValue().get(SECKILL_SPU_PREFIX+spuId);
        if (seckillSpuVO==null){
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"当前缓存没有数据，请检查预热");
        }
        LocalDateTime now = LocalDateTime.now();
        Duration afterStart = Duration.between(now, seckillSpuVO.getStartTime());
        Duration beforEnd = Duration.between(seckillSpuVO.getEndTime(),now);
        if (!(afterStart.isNegative() && beforEnd.isNegative())){
            seckillSpuVO.setUrl(null);
        }
        return seckillSpuVO;
    }

    @Override
    public SeckillSpuDetailSimpleVO getSeckillSpuDetail(Long spuId) {
        return null;
    }
}
